﻿
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using demo.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Reflection;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;

namespace demo
{



    public class 锚杆
    {
        private ExternalCommandData _commandData;

        protected readonly Document document;

        public 锚杆(ExternalCommandData commandData)
        {
            _commandData = commandData; 
            document = _commandData.Application.ActiveUIDocument.Document;
        }

        public void Test()
        {
            // 普通锚杆();
            // 面锚杆();

            // 弧线锚杆();

            // 钢管();
            // 锚杆2();

            //弧形面();
            //弧上绘制锚杆();

            // 平面坐标弧上画锚杆();


            //平面坐标弧上画锚杆();

            弧上绘制锚杆2();

        }


        public void 弧上绘制锚杆2()
        {

              var OX = -8.1036745406824142;
              var OY= 7.7755905511811019;
              var R= 26.607611548556431;
              var StartAngle= -10d;
              var TotalAngle= 10d;
              var VerticalX= 18.402687012874203;
              var VerticalY= 5.4565844039254987;
              var X0= 18.099707601473121;
              var X1= 18.503937007874015;
              var Y0= 3.1552272937047077;
              var Y1= 7.7755905511811019;


            Curve arc = Arc.Create(new XYZ(18.099707601473121, 0, 3.1552272937047077), new XYZ(18.503937007874015, 0, 7.7755905511811019), new XYZ(18.402687012874203, 0, 5.4565844039254987));
           // Curve arc = Arc.Create(new XYZ(-5, 0, 0), new XYZ(5, 0, 0), new XYZ(0, 0, 5));
            Transaction t = new Transaction(document, "info12");
            t.Start();
            arc.CreateModelCurve(document);


            arc.MakeBound(arc.ComputeRawParameter(-0.01), arc.ComputeRawParameter(1.01));

            //arc.CreateModelCurve(document);

           // var point = arc.Evaluate(arc.GetEndParameter(0)+1, false);

            //180 * l / Math.PI * arcPoint.R       180 * s / (Math.PI * R)
            var s = 2.5;
             var point = new XYZ(R * Math.Cos(-(8.3067209853483339*Math.PI)/180) + OX, 0, R * Math.Sin(-(8.3067209853483339 * Math.PI) / 180) + OY);
            //var point = new XYZ(R * Math.Cos(2) + OX, 0, R * Math.Sin(2) + OY);

            var r = R;
            var l = 2;
            var _x = (point.X - OX) / r * (r + l) + OX;
            var _y = (point.Z - OY) / r * (r + l) + OY;
           
            var l2 = Line.CreateBound(point, new XYZ(_x, 0, _y));
            l2.CreateModelCurve(document);

            t.Commit();
        }



        public void 弧上绘制锚杆()
        {
            /// 已经实现
            Curve arc = Arc.Create(new XYZ(-5, 0, 0), new XYZ(5, 0, 0), new XYZ(0, 0, 5));
            Transaction t = new Transaction(document, "info12");
            t.Start();
            arc.CreateModelCurve(document);
            var raw = arc.GetEndParameter(0);
            for (int i = 0; i < 30; i++)
            {
                raw = raw + 0.1;
                var point = arc.Evaluate(raw, false);
                //var _x = (point.X-arc.OX.MM()) /r * (r+ 2)+ arc.OX.MM();
                // 弧上的点x  - 弧的圆心x  /  R  * (r+锚杆长) + 圆心x
                var _x = (point.X - 0) / 5 * (5 + 2) + 0;
                var _y = (point.Z - 0) / 5 * (5 + 2) + 0;
                var l2 = Line.CreateBound(point, new XYZ(_x, 0, _y));
                l2.CreateModelCurve(document);
            }

            t.Commit();
        }

        public void 平面坐标弧上画锚杆()
        {
            double L = 20;
            Curve arc = Arc.Create(new XYZ(-5, 0, 0), new XYZ(5, 0, 0), new XYZ(0, 5, 0));
            var listCurve = new List<Curve>();
            listCurve.Add(arc);
            listCurve.Add(Line.CreateBound(new XYZ(5, 0, 0),new XYZ(-5, 0, 0)));
            var arcEntity = new Profile(listCurve);
            var l1 = Line.CreateBound(new XYZ(0,0,0), new XYZ(0, 20, 0));
            var path = new CurveLoop();
            path.Append(l1);

            Transaction t = new Transaction(document, "info12");
            t.Start();
            var solid = arcEntity.CreateSweptGeometry(path, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));
            Create(solid);

            Profile profile = Profile.CreateCircle(0.1);

            double yL = 0.1;

            for (int i = 0; i < 10; i+=2)
            {
                double para = i * yL / L;
                Transform transform1 = TransformUtils.GetTransform(l1, para);
                CurveLoop path1 = new CurveLoop();
                path1.Append(arc.CreateTransformed(transform1));
                Solid solid1 = profile.CreateSweptGeometry(path1, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));
                Create(solid1);
            }





            //var raw = arc.GetEndParameter(0);
            //for (int i = 0; i < 30; i++)
            //{
            //    raw = raw + 0.1;
            //    var point = arc.Evaluate(raw, false);
            //    //var _x = (point.X-arc.OX.MM()) /r * (r+ 2)+ arc.OX.MM();
            //    // 弧上的点x  - 弧的圆心x  /  R  * (r+锚杆长) + 圆心x
            //    var _x = (point.X - 0) / 5 * (5 + 2) + 0;
            //    var _y = (point.Z - 0) / 5 * (5 + 2) + 0;
            //    var l2 = Line.CreateBound(point, new XYZ(_x, 0, _y));
            //    l2.CreateModelCurve(document);
            //}

            t.Commit();

        }



        public void 弧形面()
        {
            var p1 = new XYZ(0, 0, 0);
            var p2 = new XYZ(20, 0, 0);
            var po = new XYZ(10, 5, 0);
            var arc = Arc.Create(p1, p2, po);

            var raw = arc.GetEndParameter(0) - 5;
            var point = arc.Evaluate(raw, false);

            var test = new SketchPlaneTest();

            Transaction tran1 = new Transaction(document, "22222");
            tran1.Start();
            SketchPlane sketch = test.CreateSketchPlane(document, XYZ.BasisZ, XYZ.Zero);

            var l = Line.CreateBound(point,new XYZ(20,10,0));

            test.Get(sketch, arc);

            test.Get(sketch, l);


            tran1.Commit();




            //var line = Line.CreateBound(p2, p1);
            //CurveLoop loop = new CurveLoop();
            //loop.Append(arc);
            //loop.Append(line);

            //var path = new CurveLoop();
            //path.Append(Line.CreateBound(new XYZ(0, 0, 0), new XYZ(0, 50, 0))); ;

            //var profile = new Profile(loop);
            //var solid = profile.CreateSweptGeometry(path, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));
            //Transaction tran = new Transaction(document, "22222");
            //tran.Start();



            //DirectShape ds = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
            //ds.SetShape(new List<GeometryObject>() { solid });
           
            
            
            
            
            //tran.Commit();

            //Transaction t = new Transaction(document, "22222");
            //t.Start();
            //Solid sd=null;

            //DirectShape ds1 = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
            //var box = new EntityInfo();
            //var solid1 = box.CreateCylinder(XYZ.Zero, 2, 40, GeometryCreation.CylinderDirection.BasisZ);
            //ds1.SetShape(new List<GeometryObject>() { solid1 });



           
            //t.Commit();







        }



        public void 普通锚杆()
        {
          

            var l1 = Line.CreateBound(new XYZ(0,0,0),new XYZ(120,0,0));


            var l2 = Line.CreateBound(new XYZ(0, 20, 0), new XYZ(120, 20, 0));


            var r1 = Arc.Create(new XYZ(0,0,0),new XYZ(100,0,0),new XYZ(50,20,0));
           // var r2 = Arc.Create(new XYZ(0, 20, 0), new XYZ(100, 20, 0), new XYZ(50, 20, 0));


            var list = new List<Curve>();
            list.Add(l1);
            list.Add(l2);


            double distance = 5;  //间距
            Line line = Line.CreateBound(XYZ.Zero, new XYZ(0,100,0));
            int count = (int)Math.Floor(line.Length / distance);
            for (int i = 1; i < count; i+=2)
            {
                double para1 = i * distance / line.Length;
                Transform transform1 = TransformUtils.GetTransform(line, para1);
                var radius = 2;// 半径
                var profile = Profile.CreateCircle(radius);

                foreach (var item in list)
                {
                    CurveLoop path = new CurveLoop();
                    path.Append(item.CreateTransformed(transform1));
                    Solid solid = profile.CreateSweptGeometry(path, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));


                    Transaction tran = new Transaction(document, "方块");
                    tran.Start();
                    DirectShape ds = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
                    var box = new EntityInfo();
                   
                    ds.SetShape(new List<GeometryObject>() { solid });
                    tran.Commit();


                    //var category = Category.GetCategory(document, BuiltInCategory.OST_Roads);
                    //DirectShapeType directShapeType = DirectShapeType.Create(document, "锚杆", category.Id);

                    //DirectShape directShape = DirectShape.CreateElement(document, Category.GetCategory(document, BuiltInCategory.OST_Roads).Id);
                    //directShape.SetTypeId(directShapeType.Id);

                    //directShape.SetShape(new List<GeometryObject>() { solid });
                    

                }


            }





        }


        public void 面锚杆()
        {
           
            var profile = Profile.CreateRectangle(100,120);
            Solid solid = profile.CreateExtrusionGeometry(153, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));
            var so = new List<GeometryObject>();
            foreach (var face in solid.Faces)
            {


                if (face is PlanarFace)
                {

                    var f = face as PlanarFace;
                    var anchorRod = new GenericAnchorRod();
                    anchorRod.Material = null;
                    anchorRod.R = 2;

                    var s = anchorRod.Arrange(f, 20, 5);
                    so.AddRange(s);

                }

              
            }


            Transaction tran = new Transaction(document, "方块");
            tran.Start();
            DirectShape ds = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
           // ds.SetShape(new List<GeometryObject>() { solid });
            ds.SetShape(so);


           
            tran.Commit();



        }

        public void 弧线锚杆()
        {
            var p1 = new XYZ(0, 0, 0);
            var p2 = new XYZ(20, 0, 0);
            var po = new XYZ(10, 5, 0);

            var arc = Arc.Create(p1, p2, po);
            var line = Line.CreateBound(p2, p1);

            var r = 12.5;

            



            CurveLoop loop = new CurveLoop();
            loop.Append(arc);
            loop.Append(line);

            var path = new CurveLoop();
            path.Append(Line.CreateBound(new XYZ(0, 0, 0), new XYZ(0, 50, 0))); ;

            var profile = new Profile(loop);
            var solid = profile.CreateSweptGeometry(path, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));


            Transaction tran = new Transaction(document, "方块1");
            tran.Start();
            DirectShape ds = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
            ds.SetShape(new List<GeometryObject>() { solid });

            tran.Commit();
            var arcL = Profile.CreateCircle(0.2);
            var path_1 = new CurveLoop();
            path_1.Append(Line.CreateBound(new XYZ(10, 0, 5), new XYZ(10, 0, 10)));
            var solid_1 = arcL.CreateSweptGeometry(path_1, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));

            var arcL2 = Profile.CreateCircle(0.2);

            var path_2 = new CurveLoop();
            path_2.Append(Line.CreateBound(new XYZ(8.2603, 0, 4.8784), new XYZ(6.8378, 5, 14.7810)));
            var solid_2 = arcL2.CreateSweptGeometry(path_2, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));



            Transaction tran2 = new Transaction(document, "方块1");
            tran2.Start();
            DirectShape ds2 = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
            ds2.SetShape(new List<GeometryObject>() { solid_2 });

            tran2.Commit();



        }


        public void 钢管()
        {
          
          

            var path = new CurveLoop();
            path.Append(Line.CreateBound(new XYZ(0, 0, 0), new XYZ(0, 50, 0))); ;

            var arc = Profile.CreateCircle(2);
            arc.InnerProfile = Profile.CreateCircle(0.5);
           
            var solid = arc.CreateSweptGeometry(path, new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId));


            Transaction tran = new Transaction(document, "3333");
            tran.Start();
            DirectShape ds = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
            ds.SetShape(new List<GeometryObject>() { solid });

            tran.Commit();
          
        }


        public void 锚杆2()
        {
           
            Transaction tran = new Transaction(document, "圆主体");
            tran.Start();
          
            
            DirectShape ds = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
            var box = new EntityInfo();
            var solid = box.CreateCylinder(XYZ.Zero, 2, 40, GeometryCreation.CylinderDirection.BasisZ);
            ds.SetShape(new List<GeometryObject>() { solid });
            var id = ds.Id;
            int l = 10;
            for (int i = 0; i < 10; i++)
            {
                ElementTransformUtils.CopyElement(document, id, new XYZ(l, 10, 0));
                l += 10;
            }




            CreateRevolvedGeometry(box.Profileloops, 23, 10);


            tran.Commit();


        }
        public virtual Solid CreateRevolvedGeometry(List<CurveLoop> loops, double startAngle, double endAngle)
        {
            Frame frame = new Frame(XYZ.Zero, XYZ.BasisX, XYZ.BasisZ, -XYZ.BasisY);
            return GeometryCreationUtilities.CreateRevolvedGeometry(frame, loops, startAngle, endAngle);
        }

        public DirectShape Create(Solid solid)
        {
            DirectShape shape = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
            shape.AppendShape(new List<GeometryObject>() { solid });
            return shape;
        }


    }









    public abstract class AnchorRod
    {
        public Material Material { get; set; }

        public double R { get; set; }

       

        public Profile Profile { get { return Profile.CreateCircle(R); } }



        private Solid CreateSolid(XYZ origin, XYZ direction, double length)
        {
            CurveLoop path = new CurveLoop();
            path.Append(Line.CreateBound(origin, origin + direction * length));

            var materialId = Material == null ? ElementId.InvalidElementId : Material.Id;
            return Profile.CreateSweptGeometry(path, new SolidOptions(materialId, ElementId.InvalidElementId));
        }

        /// <summary>
        /// 在面上布置锚杆
        /// </summary>
        /// <param name="face"></param>
        /// <param name="length"></param>
        /// <param name="space">间距</param>
        /// <returns></returns>
        public List<Solid> Arrange(Face face, double length, double space)
        {
            var solids = new List<Solid>();

            var boxUV = face.GetBoundingBox();//GetBoundingBox 返回面的UV边界框。
            var max = boxUV.Max;
            var min = boxUV.Min;

            // 梅花布置         
            for (double i = min.U + space; i < max.U; i += 2 * space)
            {
                for (double j = min.V + space; j <= max.V; j += 2 * space)
                {
                    UV uv = new UV(i, j);
                    if (face.IsInside(uv))
                    {
                        solids.Add(CreateSolid(face.Evaluate(new UV(i, j)), face.ComputeNormal(new UV(i, j)), length));
                    }
                }
            }
            for (double i = min.U + 2 * space; i < max.U; i += 2 * space)
            {
                for (double j = min.V + 2 * space; j <= max.V; j += 2 * space)
                {
                    UV uv = new UV(i, j);
                    if (face.IsInside(uv))
                    {
                        solids.Add(CreateSolid(face.Evaluate(new UV(i, j)), face.ComputeNormal(new UV(i, j)), length));
                    }
                }
            }
            return solids;
        }

    }

    /// <summary>
    /// 一般普通锚杆
    /// </summary>
    public class GenericAnchorRod: AnchorRod
    {
        public GenericAnchorRod()
        {

        }
    
    }
    /// <summary>
    /// 注浆锚杆
    /// </summary>
    public class HollowGroutingBolt: AnchorRod
    {
        /// <summary>
        /// 表示中空锚杆时的壁厚
        /// </summary>
        public double Thickness { get; set; }
        public HollowGroutingBolt()
        {
            Profile.InnerProfile= Profile.CreateCircle(R - Thickness);
        }
    }


    public class MaoGan
    {
        private readonly Document _document;
        public MaoGan(Document document)
        {
            _document = document;
        }

        public void Create()
        {
            Profile profile = Profile.CreateCircle(10);


        }

        







    }

    public class TunnelEntityType
    {
      
    }




}
